using UnityEngine;
using System.Collections;

public class ManagerAnimationUV : MonoBehaviour
{
	#region Attributes
	
	public bool changeAutommaticAlpha = true;
	
	[SerializeField]
	//Animation to be play on start
	private string animationOnStart = string.Empty;
	
	//Animations of this object.
	[SerializeField]
	private InfoAnimation[] animations;
	
	//Current animtion
	private InfoAnimation currentAnimation;
	
	//It's playing any animation ?
	private bool isPlaying;
	
	//It's playing crescent frames? (Used only ping pong wrap mode)
	private bool growingFrames;
	
	#region To play
	
	//Current frame
	private int currentFrame;
	
	//Current cut position of UV
	private Vector2 actualPosition;
	
	//Mesh that will be remapped(Plane).
	private Mesh mesh;
	
	//Verticles of mesh(Plane :P).
	private Vector3[] vertices;
	
	//UV map.
	private Vector2[] uvs;
	
	//Current time .
	private float currentTime;
	
	#endregion To play;
	
	#endregion Attributes;
	
	#region Getters and Setters
	
	public bool IsPlaying
	{
		get 
		{ 
			return isPlaying;
		}
	}
	
	//Get the current animation.
	public InfoAnimation GetCurrentAnimation
	{
		get { return currentAnimation; }
	}
	
	//Can change to other animation ?
	public bool CanChangeAnimation
	{
		get 
		{
			if(currentAnimation != null)
			{
				if(currentAnimation.GetWrapMode == InfoAnimation.SimpleUVWrapMode.once ||
				   currentAnimation.GetWrapMode == InfoAnimation.SimpleUVWrapMode.pingPong)
					return !isPlaying;
			}
			
			return true;
		}
	}
	
	#endregion Getters and Setters;
	
	void Awake()
	{
		mesh = GetComponentInChildren<MeshFilter>().mesh;
		
		img = renderer.material.mainTexture;
		
		if(!animationOnStart.Equals(string.Empty))
		{
			Play(animationOnStart);
		}
	}
	
	Texture img;
	
	/// <summary>
	/// Play the specified animationName.
	/// </summary>
	/// <param name='animationName'>
	/// Animation name.
	/// </param>
	public void Play(string animationName)
	{
		//If the current animation not equal of received animation...
		if(currentAnimation == null || !currentAnimation.GetName.Equals(animationName))
		{
			foreach(InfoAnimation a in animations)
			{
				//If found the animation on list of animation: Update the current animation.
				if(a.GetName.Equals(animationName))
				{
					currentAnimation = a;
					currentTime = 0;
					currentFrame = currentAnimation.GetInitialFrame;
					isPlaying = true;
					growingFrames = true;
					
					//if(GetComponentInChildren<Renderer>().sharedMaterial.mainTexture != currentAnimation.GetImage)
					//{
						img = currentAnimation.GetImage;
					//}
					
					break;
				}
			}
		}
	}
	
	public void GoToFrameOf(string animationName, int frame)
	{
		//If the current animation not equal of received animation...
		if(currentAnimation == null || !currentAnimation.GetName.Equals(animationName))
		{
			foreach(InfoAnimation a in animations)
			{
				//If found the animation on list of animation: Update the current animation.
				if(a.GetName.Equals(animationName))
				{
					currentAnimation = a;
					GetComponentInChildren<Renderer>().sharedMaterial.mainTexture = currentAnimation.GetImage;
					break;
				}
			}
		}
		
		currentFrame = frame;
		actualPosition.x = currentFrame % currentAnimation.NumTiles.x;
		actualPosition.y = (currentFrame - actualPosition.x) / currentAnimation.NumTiles.x;
				
		vertices = mesh.vertices;
		uvs = new Vector2[vertices.Length];
		
		uvs[0] = new Vector2((1/currentAnimation.NumTiles.x)*actualPosition.x,(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-(actualPosition.y+1)));
		uvs[1] = new Vector2((1/currentAnimation.NumTiles.x)*actualPosition.x,(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-actualPosition.y));
		uvs[2] = new Vector2((1/currentAnimation.NumTiles.x)*(actualPosition.x+1),(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-actualPosition.y));
		uvs[3] = new Vector2((1/currentAnimation.NumTiles.x)*(actualPosition.x+1),(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-(actualPosition.y+1)));
		
		mesh.uv = uvs;
	}
	
	/// <summary>
	/// Stop the current animation.
	/// </summary>
	public void Stop()
	{
		isPlaying = false;
		currentAnimation = null;
	}
	
	void Update()
	{
		if(isPlaying)
		{
			if(mesh)
			{
				if(currentAnimation != null)
				{
					if(currentTime < currentAnimation.GetTime)
					{
						currentTime += Time.deltaTime;
					}
					else
					{
						currentTime = 0;
						
						if(currentAnimation.GetWrapMode == InfoAnimation.SimpleUVWrapMode.once ||
						   currentAnimation.GetWrapMode == InfoAnimation.SimpleUVWrapMode.loop)
						{
							currentFrame ++;
							
							if(currentFrame > currentAnimation.GetFinalFrame)
							{
								switch(currentAnimation.GetWrapMode)
								{
									case InfoAnimation.SimpleUVWrapMode.once:
									currentFrame = currentAnimation.GetFinalFrame;
									isPlaying = false;
									break;
									
									case InfoAnimation.SimpleUVWrapMode.loop:
									currentFrame = currentAnimation.GetInitialFrame;
									break;
								}
							}
						}
						else if(currentAnimation.GetWrapMode == InfoAnimation.SimpleUVWrapMode.pingPong ||
							    currentAnimation.GetWrapMode == InfoAnimation.SimpleUVWrapMode.loopPingPong)
						{
							if(growingFrames)
							{
								currentFrame ++;
								
								if(currentFrame == currentAnimation.GetFinalFrame)
								{
									growingFrames = false;
								}
							}
							else
							{
								currentFrame --;
								
								if(currentFrame <= currentAnimation.GetInitialFrame)
								{
									switch(currentAnimation.GetWrapMode)
									{
										case InfoAnimation.SimpleUVWrapMode.pingPong:
										currentFrame = currentAnimation.GetInitialFrame;
										isPlaying = false;
										break;
										
										case InfoAnimation.SimpleUVWrapMode.loopPingPong:
										growingFrames = true;
										break;
									}
								}
							}
						}
					}
					
					actualPosition.x = currentFrame % currentAnimation.NumTiles.x;
					actualPosition.y = (currentFrame - actualPosition.x) / currentAnimation.NumTiles.x;
					
					vertices = mesh.vertices;
					uvs = new Vector2[vertices.Length];
					
					uvs[0] = new Vector2((1/currentAnimation.NumTiles.x)*actualPosition.x,(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-(actualPosition.y+1)));
					uvs[1] = new Vector2((1/currentAnimation.NumTiles.x)*actualPosition.x,(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-actualPosition.y));
					uvs[2] = new Vector2((1/currentAnimation.NumTiles.x)*(actualPosition.x+1),(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-actualPosition.y));
					uvs[3] = new Vector2((1/currentAnimation.NumTiles.x)*(actualPosition.x+1),(1/currentAnimation.NumTiles.y)*(currentAnimation.NumTiles.y-(actualPosition.y+1)));
					
					GetComponentInChildren<Renderer>().sharedMaterial.mainTexture = img;
					
					mesh.uv = uvs;
					
					if(changeAutommaticAlpha && renderer.material.color.a != 1)
					{	
						renderer.material.color = new Color(renderer.material.color.r, renderer.material.color.g,
												  renderer.material.color.b, 1);
					}
				}
			}
			else
			{
				Debug.LogWarning("Nao há mesh");
			}
		}
	}
}
